package Taverna;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import javax.portlet.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import tavernacon.*;

public class MyPortlet extends GenericPortlet {

    private static final String NORMAL_VIEW = "/normal.jsp";
    private static final String MAXIMIZED_VIEW = "/maximized.jsp";
    private static final String HELP_VIEW = "/help.jsp";
    private PortletRequestDispatcher normalView;
    private PortletRequestDispatcher maximizedView;
    private PortletRequestDispatcher helpView;

    public void doView(RenderRequest request, RenderResponse response)
            throws PortletException, IOException {

        PortletSession session = request.getPortletSession();
        String[] inputKeys;

        try {

            InputStream inputStream = MyPortlet.class.getClassLoader().getResourceAsStream("../workflowDetails.xml");
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
            String line = br.readLine();
            String xml = "";
            while (line != null) {
                System.out.println(line);
                xml += line;
                line = br.readLine();
            }

            File temp = new File("interface");
            BufferedWriter bw = null;
            //String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SOMETAG>Content</SOMETAG>";

            PrintWriter w = new PrintWriter(temp);
            bw = new BufferedWriter(w);
            bw.write(xml);
            bw.flush(); //<---- Make sure you flush the buffer contents into the file.


            DocumentBuilderFactory Factory = DocumentBuilderFactory.newInstance();
            Factory.setNamespaceAware(true);
            DocumentBuilder builder = Factory.newDocumentBuilder();
            Document doc = builder.parse(temp);
            //creating an XPathFactory:
            XPathFactory factory = XPathFactory.newInstance();
            //using this factory to create an XPath object:
            XPath xpath = factory.newXPath();

            XPathExpression nameExpr = xpath.compile("/workflow/name/text()");
            Object nameResult = nameExpr.evaluate(doc, XPathConstants.NODESET);
            NodeList nameNodeList = (NodeList) nameResult;

            XPathExpression descExpr = xpath.compile("/workflow/description/text()");
            Object descResult = descExpr.evaluate(doc, XPathConstants.NODESET);
            NodeList descNodeList = (NodeList) descResult;

            XPathExpression typeExpr = xpath.compile("//inputs/input/type/text()");
            Object typeResult = typeExpr.evaluate(doc, XPathConstants.NODESET);
            NodeList typeNodeList = (NodeList) typeResult;

            XPathExpression inputExpr = xpath.compile("//inputs/input/name/text()");
            Object inputResult = inputExpr.evaluate(doc, XPathConstants.NODESET);
            NodeList inputNodeList = (NodeList) inputResult;

            XPathExpression exampleExpr = xpath.compile("//inputs/input/example/text()");
            Object exampleResult = exampleExpr.evaluate(doc, XPathConstants.NODESET);
            NodeList exampleNodeList = (NodeList) exampleResult;

            XPathExpression descriptionExpr = xpath.compile("//inputs/input/description/text()");
            Object descriptionResult = descriptionExpr.evaluate(doc, XPathConstants.NODESET);
            NodeList descriptionNodeList = (NodeList) descriptionResult;


            inputKeys = new String[typeNodeList.getLength()];

            response.setContentType("text/html");
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
            out.print("<style type=\"text/css\">h3 {color:#3366CC;}r.title {color:#666666;}r.value {font-style:italic;color:#666666} table, td{border:0px solid black;}td{padding:4px;}</style>");
            out.print("<h3>" + nameNodeList.item(0).getNodeValue() + "</h3>");
            out.print("<br/><r class=\"value\">" + descNodeList.item(0).getNodeValue() + "</r>");
            out.print("<BR/><form method=\"post\" action=" + response.createActionURL() + ">");
            out.print("<table cellpadding=\"10\">");
            for (int i = 0; i < typeNodeList.getLength(); i++) {
                inputKeys[i] = inputNodeList.item(i).getNodeValue();
                if (typeNodeList.item(i).getNodeValue().equals("dropdown")) {

                    XPathExpression valuesExpr = xpath.compile("//inputs/input[" + (i + 1) + "]/values/value/text()");
                    Object valuesResult = valuesExpr.evaluate(doc, XPathConstants.NODESET);
                    NodeList valuesNodeList = (NodeList) valuesResult;

                    out.print("<tr><td><b>" + inputNodeList.item(i).getNodeValue() + "</b></td>");

                    out.print("<td><select name=\"" + inputNodeList.item(i).getNodeValue() + "\">");
                    for (int j = 0; j < valuesNodeList.getLength(); j++) {
                        out.print("<option value=\"" + valuesNodeList.item(j).getNodeValue() + "\">" + valuesNodeList.item(j).getNodeValue() + "</option>");
                    }
                    out.print("</td></tr>");
                    out.print("<tr><td><r class=\"title\">Description</r></td>");
                    out.print("<td><r class=\"value\">" + descriptionNodeList.item(i).getNodeValue() + "</r></td></tr>");
                    out.print("<tr><td><r class=\"title\">Example</r></td>");
                    out.print("<td><r class=\"value\">" + exampleNodeList.item(i).getNodeValue() + "</r></td></tr>");
                } else {
                    out.print("<tr><td><b>" + inputNodeList.item(i).getNodeValue() + "</b></td><td><INPUT type=\"text\" name=\"" + inputNodeList.item(i).getNodeValue() + "\" size=\"20\"></td></tr>");
                    out.print("<tr><td><r class=\"title\">Description</r></td>");
                    out.print("<td><r class=\"value\">" + descriptionNodeList.item(i).getNodeValue() + "</r></td></tr>");
                    out.print("<tr><td><r class=\"title\">Example</r></td>");
                    out.print("<td><r class=\"value\">" + exampleNodeList.item(i).getNodeValue() + "</r></td></tr>");
                }
            }
            out.print("</table><INPUT type=\"submit\" name=\"SUBMIT\" value=\"Run\">" +
                    "</form>");

            if (session.getAttribute("jobID") == null) {
                out.print("<br/>No jobs in session");
            }
            else{
                out.print("<br/>ID of last job run: <b>"+session.getAttribute("jobID")+"</b>");
            }

            session.setAttribute("inputKeys", inputKeys);

            /*create a link back to the portlet using a PortletURL
            out.print("<A href=\"");
            out.print(response.createRenderURL());
            out.print("\">Select a different workflow</A>");*/

        } catch (Exception e) {
            System.out.println(e + ": " + e.getLocalizedMessage());
            e.printStackTrace();
        }

    }

    protected void doHelp(RenderRequest request, RenderResponse response)
            throws PortletException, IOException {

        helpView.include(request, response);

    }

    public void processAction(ActionRequest request, ActionResponse response) throws PortletException, java.io.IOException {

        PortletSession session = request.getPortletSession();
        String[] inputKeys = (String[]) session.getAttribute("inputKeys");

        String jobIdStr = "";

        System.out.println("run");
        try {

            String[] inputValues = new String[inputKeys.length];
            for (int i = 0; i < inputKeys.length; i++) {
                inputValues[i] = request.getParameter(inputKeys[i]);
                //System.out.println("INPUT: " + input);
            }

            for (int i = 0; i < inputValues.length; i++) {
                System.out.println(inputKeys[i] + ": " + inputValues[i]);
            }

            //get workflow details
            InputStream inputStream = MyPortlet.class.getClassLoader().getResourceAsStream("../workflowDetails.xml");
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
            String line = br.readLine();
            String xml = "";
            while (line != null) {
                xml += line;
                line = br.readLine();
            }

            //create a temporary file to parse with XPath
            File temp = new File("interface");
            BufferedWriter bw = null;
            //String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SOMETAG>Content</SOMETAG>";

            PrintWriter w = new PrintWriter(temp);
            bw = new BufferedWriter(w);
            bw.write(xml);
            bw.flush(); //<---- Make sure you flush the buffer contents into the file.


            DocumentBuilderFactory Factory = DocumentBuilderFactory.newInstance();
            Factory.setNamespaceAware(true);
            DocumentBuilder builder = Factory.newDocumentBuilder();
            Document doc = builder.parse(temp);
            //creating an XPathFactory:
            XPathFactory factory = XPathFactory.newInstance();
            //using this factory to create an XPath object:
            XPath xpath = factory.newXPath();

            XPathExpression idExpr = xpath.compile("/workflow/idonserver/text()");
            Object idResult = idExpr.evaluate(doc, XPathConstants.NODESET);
            NodeList idNodeList = (NodeList) idResult;

            XPathExpression serverExpr = xpath.compile("/workflow/serverLocation/text()");
            Object serverResult = serverExpr.evaluate(doc, XPathConstants.NODESET);
            NodeList serverNodeList = (NodeList) serverResult;

            RESTClient tavernaRESTClient = new RESTClient();
            tavernaRESTClient.setBaseURL(serverNodeList.item(0).getNodeValue());

            Map<String, DataValue> ds = new HashMap<String, DataValue>();

            /*int noOfInputs = containerComponent.getChildren().size();

            for (int i = 0; i < noOfInputs; i = i + 6) {
            HtmlOutputText name = (HtmlOutputText) containerComponent.getChildren().get(i);//.getChildren().get(0);
            HtmlInputText in = (HtmlInputText) containerComponent.getChildren().get(i + 1);//.getChildren().get(1);
            //HtmlInputText hit = (HtmlInputText) obj;
            ds.put((String) name.getValue(), new DataValue((String) in.getValue()));

            String str = (String) name.getValue() + ", " + (String) in.getValue();
            System.out.println(str);
            }*/

            for (int i = 0; i < inputKeys.length; i++) {
                ds.put(inputKeys[i], new DataValue(inputValues[i]));
            }

            Long inputID = tavernaRESTClient.addData(new DataResource(ds));
            System.out.println("DataId :" + inputID);


            /*String workflowXML = IOUtils.toString(getClass().getResource("../test/pipeline.t2flow").openStream());
            Long workflowID = tavernaRESTClient.addWorkflow(workflowXML);
            System.out.println("WorkflowId :"+ workflowID);*/

            String wfidStr = idNodeList.item(0).getNodeValue();//(String) session.getAttribute("workflowID");//idNodeList.item(0).getNodeValue();
            System.out.println("Workflow ID: " + wfidStr);
            long wfid = Long.parseLong(wfidStr);
            long startTime = System.currentTimeMillis();
            long duration = 0;
            Long jobID = tavernaRESTClient.addJob(wfid, inputID);
            jobIdStr = jobID.toString();
            System.out.println("JobId :" + jobIdStr);
            session.setAttribute("jobID", jobIdStr);

        } catch (Exception e) {
            System.out.println(e);
        }

    }

    public void init(PortletConfig config) throws PortletException {
        super.init(config);
        normalView = config.getPortletContext().getRequestDispatcher(NORMAL_VIEW);
        maximizedView = config.getPortletContext().getRequestDispatcher(MAXIMIZED_VIEW);
        helpView = config.getPortletContext().getRequestDispatcher(HELP_VIEW);
    }

    public void destroy() {
        normalView = null;
        maximizedView = null;
        helpView = null;
        super.destroy();
    }
}
